package com.px.baolaiapi.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.px.mbg.mapper.FileManaMapper;
import com.px.mbg.model.FileMana;
import com.px.baolaiapi.service.IFileManaService;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 文件管理 服务实现类
 * </p>
 *
 * @author 品讯科技
 * @since 2022-03-04
 */
@Service
public class FileManaServiceImpl extends ServiceImpl<FileManaMapper, FileMana> implements IFileManaService {
    //定义根路径
    public static final String ROOTPATH = "D:\\cam/path";
    //public static final String FILEROOTPATH = "/Itts016/编程图纸/";
    //public static final String FILEROOTPATH = "\\\\192.168.1.202\\编程图纸\\";
    public static final String FILEROOTPATH = "\\\\192.168.3.235\\编程图纸\\";

    /**
     * 添加文件夹
     *
     * @param fileMana 文件的魔法
     * @return int
     */
    @Override
    public int addFileFolder(FileMana fileMana) {
        Long manaId = fileMana.getId();
        List<FileMana> list = this.list(new QueryWrapper<FileMana>().lambda().eq(FileMana::getName, fileMana.getName()).eq(FileMana::getParentId, manaId));
        if (CollectionUtil.isNotEmpty(list)) {
            return -1;
        }

        String parentPath = "";
        if (manaId == 0) {
            parentPath = ROOTPATH;
        } else {
            FileMana mana = this.getById(manaId);
            parentPath = mana.getFilepath();
        }

        FileMana fileMana1 = new FileMana();
        fileMana1.setName(fileMana.getName());
        String path = parentPath + "/" + fileMana.getName();
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        fileMana1.setFilepath(path);
        fileMana1.setParentId(manaId);
        fileMana1.setFiletype(1);
        return this.save(fileMana1) ? 1 : 0;

    }

    /**
     * 上传文件
     *
     * @param parentId 文件的魔法
     * @param files    文件
     * @return int
     */
    @SneakyThrows
    @Override
    public int addFile(long parentId, MultipartFile[] files) {
        if (files.length > 0) {

            for (MultipartFile file : files) {
                String fileName = file.getOriginalFilename();
//                System.out.println("fileName = " + fileName);
                this.remove(new QueryWrapper<FileMana>().lambda().eq(FileMana::getName, fileName).eq(FileMana::getParentId, parentId));
//                List<FileMana> list = this.list(new QueryWrapper<FileMana>().lambda().eq(FileMana::getName, fileName).eq(FileMana::getParentId, parentId));
//                if (CollectionUtil.isNotEmpty(list)) {
//                    return -1;
//                }
            }
            String parentPath = "";
            if (parentId == 0) {
                parentPath = ROOTPATH;
            } else {
                FileMana mana = this.getById(parentId);
                parentPath = mana.getFilepath();
            }
            List<FileMana> fileManas = new ArrayList<>();
            for (MultipartFile file : files) {
                String originalFilename = file.getOriginalFilename();
                String path = parentPath + "/" + originalFilename;
                FileOutputStream os = null;
                InputStream ins = null;
                try {

                    ins = file.getInputStream();
                    os = new FileOutputStream(new File(path));

                    int bytesRead = 0;
                    byte[] buffer = new byte[8192];
                    while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                        os.write(buffer, 0, bytesRead);
                    }

                    FileMana fileMana1 = new FileMana();
                    fileMana1.setName(originalFilename);

                    fileMana1.setFilepath(path);
                    fileMana1.setParentId(parentId);
                    fileMana1.setFiletype(2);

                    fileManas.add(fileMana1);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (os != null) {
                            os.close();
                        }
                        if (ins != null) {
                            ins.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            if (this.saveBatch(fileManas)) {
                return 1;
            }

        } else {
            return -2;
        }

        return 0;
    }

    /**
     * 通过父级id查询全部数据
     *
     * @param parentId 父id
     * @return {@link List <FileMana>}
     */
    @Override
    public List<FileMana> queryFiles(long parentId) {
        return this.list(new QueryWrapper<FileMana>().lambda().eq(FileMana::getParentId, parentId).orderByDesc(FileMana::getFiletype,FileMana::getCreatedTime));
    }

    @Override
    public List<FileMana> queryMvcFiles(String fileName) {
        return this.list(new QueryWrapper<FileMana>().lambda().like(FileMana::getName, fileName).orderByDesc(FileMana::getFiletype,FileMana::getCreatedTime));
    }

    /**
     * 通过id删除文件和目录（包含子级）
     *
     * @param id id
     * @return int
     */
    @Override
    public int deleteFileById(long id) {
        FileMana fileMana = this.getById(id);
        if (ObjectUtil.isNotEmpty(fileMana)) {
            if (fileMana.getFiletype() == 2) {
                //删除文件
                File file = new File(fileMana.getFilepath());
                if (file.delete()) {
                    this.removeById(id);
                    return 1;
                }
            } else {
                //删除文件夹
                return remove(id) ? 1 : 0;
            }
        }
        return 0;
    }

    public boolean remove(long id) {
        FileMana fileMana = this.getById(id);
        List<FileMana> fileManas = this.list(new QueryWrapper<FileMana>().lambda().eq(FileMana::getParentId, id));
        if (CollectionUtil.isNotEmpty(fileManas)) {
            for (FileMana mana : fileManas) {
                remove(mana.getId());
            }
        }
        String filepath = fileMana.getFilepath();
        File file = new File(filepath);
        boolean delete = file.delete();
        if (delete) {
            this.removeById(id);
        }
        return delete;
//        return false;
    }

    /**
     * 重命名文件或目录
     *
     * @param id      id
     * @param newName 新名字
     * @return int
     */
    @Override
    public int rename(long id, String newName) {
        FileMana fileMana = this.getById(id);
        if (ObjectUtil.isNotEmpty(fileMana)) {
            String name = fileMana.getName();
            String filepath = fileMana.getFilepath();

            String substring = filepath.substring(0, filepath.lastIndexOf(name));
            File file = new File(filepath);
            String newPath = substring + newName;
//            String newPath = substring + "/" + newName;
            File toFile = new File(newPath);
            try {
                boolean renameTo = file.renameTo(toFile);
                if (renameTo) {
                    //更新该目录下全部的数据
                    if (fileMana.getFiletype() == 1) {
                        updateFileDir(id, newName, filepath, newPath);
                    }
                    //更新数据库
                    fileMana.setName(newName);
                    fileMana.setFilepath(toFile.getAbsolutePath());
                    this.updateById(fileMana);
                    return 1;
                }
            }catch (Exception e){
                e.printStackTrace();
            }

        }
        return 0;
    }

    public void updateFileDir(long id, String newName, String oldPath, String newPath) {
        FileMana fileMana = this.getById(id);
        if (ObjectUtil.isNotEmpty(fileMana)) {

            List<FileMana> fileManas = this.list(new QueryWrapper<FileMana>().lambda().eq(FileMana::getParentId, id));
            if (CollectionUtil.isNotEmpty(fileManas)) {
                for (FileMana mana : fileManas) {
                    updateFileDir(mana.getId(), newName, oldPath, newPath);
                }
            }
            String replace = fileMana.getFilepath().replace(oldPath, newPath);
            fileMana.setFilepath(replace);
            this.updateById(fileMana);
        }
    }

    @Override
    public void initFile(long parentId, String path) {
        int count = this.count();
        if (count>0) {
            return;
        }
//        List<FileMana> list = this.list();
//        if (CollectionUtil.isNotEmpty(list)) {
//            return;
//        }
        execInitFiles(parentId, path);
    }

    public void execInitFiles(long parentId, String path) {
        if (StringUtils.isEmpty(path)) {
            path = ROOTPATH;
        }
        File file = new File(path);
        File[] files = file.listFiles();
        if (files!=null&&files.length > 0) {
            for (File nextFile : files) {
                if (nextFile.isDirectory()) {
                    FileMana fileMana = new FileMana();
                    fileMana.setParentId(parentId);
                    fileMana.setBomId(0L);
                    fileMana.setFiletype(1);
                    fileMana.setFilepath(nextFile.getAbsolutePath());
                    String name = nextFile.getName();
                    fileMana.setName(name);
                    if (this.save(fileMana)) {
                        execInitFiles(fileMana.getId(), nextFile.getAbsolutePath());
                    }
                } else {
                    FileMana fileMana = new FileMana();
                    fileMana.setParentId(parentId);
                    fileMana.setBomId(0L);
                    fileMana.setFiletype(2);
                    fileMana.setFilepath(nextFile.getAbsolutePath());
                    String name = nextFile.getName();
                    fileMana.setName(name);
                    this.save(fileMana);
                }
            }
        }
    }
}
